package com.example.tnorder.config;


import com.example.tnorder.LoginFailureHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.filter.CharacterEncodingFilter;

import javax.annotation.Resource;
import javax.sql.DataSource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //注入数据源
    @Autowired
    private DataSource dataSource;
    @Bean //配置对象
    public PersistentTokenRepository repository(){
        JdbcTokenRepositoryImpl jdbcTokenRepository=new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
        //jdbcTokenRepository.setCreateTableOnStartup(true); //自动键表
        return jdbcTokenRepository;
    }

    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private LoginFailureHandler loginFailureHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //添加转码
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        encodingFilter.setForceEncoding(true);
        http.addFilterBefore(encodingFilter, CsrfFilter.class);


        //退出配置       发送这个请求表示退出               退出成功的跳转
        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login.html").permitAll();
        http.exceptionHandling().accessDeniedPage("/error.html"); //自定义无权限访问页面

        http.formLogin()  //设置自定义登录页面
                .loginPage("/login.html") //设置登录页面
                .loginProcessingUrl("/order/login") //指定自定义页面发送的请求
                .defaultSuccessUrl("/test1.html")//设置登录成功页面
                .failureHandler(loginFailureHandler)   //自定义失败处理
                .permitAll()
                .and().authorizeRequests()
                .antMatchers("/login.html","/static/plugins/**","/static/styles/**","/static/image/**").permitAll()
                //设置登录的用户只有拥有admin的权限才可以访问该路径，hasAuthority只针对一个权限
                .antMatchers("/test1.html").hasAuthority("admin")  //若无权限，浏览器报错403或跳转至指定页面
                .anyRequest()//任何请求
                .authenticated() //都需要认证
                .and().rememberMe().tokenRepository(repository()) //自动登录
                .tokenValiditySeconds(60*60*24*7) //设置有效时长7天
                .userDetailsService(userDetailsService)
                .and().csrf().disable(); //关闭csrf防护
    }
}
